define(function (require, exports, module) {
    const utils = require('../utils/index');
    const MD5Util = require('../utils/md5');
    var KEY = '374fa3ab6b1fae595db5382afe415bce';
    const preCheckCode = (response, opt) => {
        utils.hideLoading();
        // 通用请求判断
        if (!response) return;
        let data = response.data;
        if (data.Code === undefined || data.Code === 0) {
            return data.Data;
        }
        // 需要自定义的异常处理
        if (opt.customErrorHandle) {
            return Promise.reject(response.data || {}, response);
        }
        if (data.Code === 4002 || data.Code === 4000) {
            ELEMENT.Message.error(data.Message);
            return Promise.resolve(null);
        }
        if (data.Code === 302) {
            window.location = data.message + window.location.hash;
            return Promise.resolve(null);
        }
        if (response.data && response.data.Message) {
            ELEMENT.Message.error(data.Message);
            return Promise.resolve(null);
        }
        return Promise.reject(opt.customErrorHandle ? response.data : {}, response);
    };

    const preReject = (err, opt) => {
        utils.hideLoading();
        // 请求丢失时触发
        let response = err.response || {};
        if (err.message === 'Network Error') {
            err.message = '网络错误，请稍后再试！';
            if (!response.data) response.data = {};
            response.data.Message = '网络错误，请稍后再试！';
        }
        if (opt.customErrorHandle) {
            return Promise.reject(response.data || {}, response);
        } else if (response.data && response.data.Message) {
            setTimeout(() => {
                ELEMENT.Message.error(response.data.Message);
            }, 0);
            return Promise.resolve(null);
        } else if (err.message) {
            setTimeout(() => {
                ELEMENT.Message.error(err.message);
            }, 0);
            return Promise.resolve(null);
        }
        // customError表示是否自定义错误处理
        return Promise.reject(opt.customErrorHandle ? (response.data || {}) : {}, response);
    };


    const common = (opt = { autoCloseLoading: true, loading: true }) => {
        const { data}  = opt;
        var signStr;
        var urlStr = (opt.baseURL+opt.url).split('//')[1].toLowerCase();
        var dateStr = new Date(new Date().getTime() + 8 * 60 * 60 * 1000).toUTCString() + '+0800';

        if (!data || !Object.keys(data).length) {
          signStr = urlStr + '00000000000000000000000000000000' + dateStr + KEY;
        } else {
          signStr = urlStr + MD5Util.hexMd5(JSON.stringify(data)) + dateStr + KEY;
        }

        if (opt.loading !== false && opt.loading !== 0) {
            utils.showLoading(300, opt);
        }
        const req = {
            baseURL: '',
            method: '',
            url: '',
            data: null,
            params: null,
            headers: {
                "Content-Type": "application/json; charset=UTF-8",
            },
            responseType: "json",
            withCredentials: true,
        };

        for (const key in opt) {
            if (opt.hasOwnProperty(key)) {
                if (typeof (opt[key]) === 'undefined') delete opt[key];
            }
        }
        utils.assignDeep(req, opt);
        if(~req.baseURL.indexOf('gateway')) {
            req.headers = Object.assign(req.headers,{
                "signature": "v4:" + MD5Util.hexMd5(signStr),
                "H5-Date": dateStr,
                "Gateway-Version": 1,
                "app": "WXAgents",
            })
        }
        return axios(req).then(response => preCheckCode(response, opt), err => preReject(err, opt))
    }


    const getJSON = (opt) => {
        opt.method = 'GET';
        // if (opt.params && Object.keys(opt.params).length) {
        //     opt.paramsSerializer = params => qs.stringify(params, { indices: false });
        // }
        return common(opt);
    };

    const postJSON = (opt) => {
        opt.method = 'POST';
        return common(opt);
    };
    const putJSON = (opt) => {
        opt.method = 'PUT';
        return common(opt);
    };

    const deleteJSON = (opt) => {
        opt.method = 'DELETE';
        return common(opt);
    }
    module.exports = {
        getJSON,
        postJSON,
        putJSON,
        deleteJSON,
    }
})

